#include "bsp/cpu_driver.h"
#include "os/types.h"
#include "os/os.h"
/*
 * 主要实现1us级别的计数和delay功能，cpu的reboot
 * cpu_xxxdelay 可以安全的在中断中执行
*/

#ifdef USE_MEX_CMD
extern u32 cpu_cycle_count;
#endif

static void reboot_timer_handler(os_timer_t *t) {
	cpu_reboot();
}
static os_timer_t reboot_timer = TIMER_INIT(reboot_timer, reboot_timer_handler);

void cpu_reboot(void){
#ifndef USE_MEX_CMD
	NVIC_SystemReset();
#endif
}

void cpu_delay_reboot(uint32_t ms) {
	os_timer_post(&reboot_timer, ms);
}

void cpu_ticks_enable(void)
{
#ifndef USE_MEX_CMD
#ifdef CONFIG_CPU_TICK_TIMER
	cpu_ticks_timer_init();
#else
	CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
	DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
#endif
#endif
}

uint32_t cpu_ticks_abs(void)
{
#ifdef USE_MEX_CMD
	return cpu_cycle_count;
#else
#ifdef CONFIG_CPU_TICK_TIMER
	return cpu_tick_count();
#else
	return DWT->CYCCNT/SystemCoreClockMHz;
#endif
#endif
}

uint32_t cpu_ticks_rel(uint32_t start)
{
	uint32_t ticks = cpu_ticks_abs();

	if (ticks >= start) {
		return ticks - start;
	}

	return (0xFFFFFFFF/SystemCoreClockMHz) - start + ticks + 1;
}

static void cpu_ticks_delay(uint32_t ticks)
{
	uint32_t start;
	start = cpu_ticks_abs();
	while (cpu_ticks_rel(start) < ticks);
}

void cpu_udelay(uint32_t delay)
{
	cpu_ticks_delay(delay);
}


uint32_t cpu_get_usecond(void) {
	return cpu_ticks_abs();
}

uint32_t cpu_get_delta_us(uint32_t ticks) {
	return cpu_ticks_rel(ticks);
}


/*!
    \brief      delay a time in milliseconds
    \param[in]  count: count in milliseconds
    \param[out] none
    \retval     none
*/
void cpu_mdelay(uint32_t count)
{
	cpu_udelay(1000 * count);
}
